from collections import namedtuple
import numpy as np
# FJSPNode = Tuple[int, int, int, int]  # (作业数, 工序数, 机器数, 加工时间)

# class FJSPNode(NamedTuple):
#     task: int   # 作业
#     steps: int # 工序
#     machine: int # 机器
#     processing_time: int  # 加工时间

FJSPNode = namedtuple('FJSPNode', ['task', 'steps', 'machine', 'processing_time'])

class OperationsGraph:

    def __init__(self, path) -> None:
        '''从文件中加载问题'''
        file = open(path, 'r', encoding='utf-8')
        jobs, machines, avg_of_selectable_machines = file.readline().split()
        jobs, machines, avg_of_selectable_machines = int(jobs), int(machines), float(avg_of_selectable_machines)
        
        self.machines = machines
        self.jobs = jobs

        operation_count = 1
        operations_graph = [[FJSPNode(-1,-1,-1,-1) for _ in range(machines )], ] #第一个节点是start节点
        edges = []

        for line in file.readlines():
            if line == '\n': continue
            data = list(map(int, line.split()))
            num_steps = data.pop(0)  #每行的第一个表示该工件的工序数量
            
            for i in range(num_steps):  
                if i == 0: edges.append([0, operation_count])
                operations = [ FJSPNode(-1,0,0,0) for _ in range(machines ) ]  
                # print(operations)
                num_machines = data.pop(0)
                for j in range(num_machines):
                    machine, processing_time, *data = data
                    # print(machine, machines)
                    operations[machine - 1] = FJSPNode(operation_count, i, machine, processing_time)
                
                operations_graph.append(operations)
                operation_count += 1 

        self._edges = edges
        self._graph = operations_graph
        self.operation_count = operation_count
    
    @property
    def graph(self):
        return self._graph
    
    @property
    def graph_np(self):
        return np.array(self.graph)
    
    @property
    def edges(self):
        return np.array(self._edges)

    def __str__(self) -> str:
        return str(self._graph) \
        + str(self.edges)\
        + "\noperations = %d"%len(self._graph) \
        + "\nmachines = %d"%self.machines + "\njobs = %d"%self.jobs

if __name__ == '__main__':
    print(OperationsGraph("./Mk01.fjs"))